package pso;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Particle 
{
	public int[][] jobPositions;
	public double[][] velocity;
	public int[][] bestSolution;
	private int jobs;
	private Random r;
	public Particle(List<Integer> l, int n) //n - ilość prac (i pozycji)
	{
		jobPositions =new int[n][n];
		velocity = new double[n][n];
		bestSolution = new int[n][n];
		jobs = n;
		r = new Random();
		
		for (int i=0; i<n; i++)
		{
			jobPositions[i][l.get(i)] = 1;
			//pocztątkowe proędkości pozostają równe 0
		}
	}
	
	public int[][] copyBestSolution()
	{
		int[][] tmp = new int [jobs][jobs];
		for(int i=0; i<jobs; i++)
			for(int j=0; j<jobs; j++)
				tmp[i][j] = bestSolution[i][j];
		return tmp;
	}
	
	public void setCurrentSolutionAsBest()
	{
		for(int i=0; i<jobs; i++)
			for(int j=0; j<jobs; j++)
				bestSolution[i][j] = jobPositions[i][j];
	}
	
	public void updateVelocity(double w, double c1, double c2, double vmax, int[][] gbestSolution)	
	{
		//System.out.println("" +w +" " +c1+" " +c2+" " +vmax);
		//Printer.print(gbestSolution);
		//Printer.print(jobPositions);
		
		
		for(int j=0; j<jobs; j++)
			for(int k=0; k<jobs; k++)
			{
				velocity[k][j] = w*velocity[k][j] +  c1*r.nextFloat()*(bestSolution[k][j] - jobPositions[k][j]) + c1*r.nextFloat()*(gbestSolution[k][j] - jobPositions[k][j]);
				//co zrobić, jeśli v wyracza poza limit?
				//velocity[j][j] = velocity[j][j] % vmax;
				if(velocity[k][j]>4.0)
				{
					velocity[k][j]=4.0;
				}
				else if(velocity[k][j]< -4.0)
				{
					velocity[k][j]=-4.0;
				}
			}
		//Printer.print(velocity);
		
	}
	
	private double s(double x)
	{
		return (1/(1 + Math.exp(x)));
		
	}
	
	public void constructNewSolution(int[][] gbestSolution)	//musi mieć jeszcze najlepsze globalne rozwiązanie!
	{
		double[][] vProbs = new double[jobs][jobs];		//prawdopodobienstwa wyliczone na podstawie v
		double prob;
		double probsum = 0;
		List<Integer> jobList = new ArrayList<Integer>(jobs + 1);
		for(int i=0; i<jobs; i++)
			jobList.add(i);
		
		//for (int k=0; k<jobs; k++)
		
		int tmp=0;
		int k=0;
		int j2=0;
		double tmp2;
		
		for(int i=0; i<jobs; i++)
			for(int j=0; j<jobs; j++)
				vProbs[i][j] = s(velocity[i][j]);
		
		
		while (k<jobs)
		{
			probsum = 0;
			for(int j:jobList)
				probsum = probsum + vProbs[j][k];				
			
			/*
			System.out.println("probs:");
			Printer.print(vProbs);
			*/		
			tmp = jobList.size();
			j2=0;
			
			//for(int j:jobList)
			while(true)
			{
				prob = (vProbs[j2][k] / probsum);
				tmp2=r.nextDouble();
				/*System.out.println("\nprob" + prob +  "\nprobsum = " + probsum+   "\nvprobs =" +vProbs[j2][k]);
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}*/
				if(tmp2 <= prob)
				{
					//ustaw nowe zadanie na odpowiednim miejscu
					for(int l=0; l<jobs; l++)
					{
						jobPositions[l][k]=0;		//spr
					}
					jobPositions[j2][k] = 1;
					
					jobList.remove(jobList.indexOf(k));
					k++;
					break;
				}
				j2 = (j2+1)%tmp;
			}
		}
		
		
		
	}
}



















